/*
	Copyright (c) 2007, ANYwebcam.com Pty Ltd. All rights reserved.

	The software in this package is published under the terms of the BSD style 
	license, a copy of which has been included with this distribution in the 
	license.txt file.
*/
import com.anywebcam.di.*;
import com.anywebcam.di.util.ComponentDefinitionsLoader;
import com.anywebcam.di.util.XMLComponentDefinitionsParser;
import com.anywebcam.di.samples.movieApp.*;

import flash.utils.getDefinitionByName;

import mx.events.FlexEvent;
import mx.utils.ObjectUtil;

// --- 

/**
 * Force Inclusion into the SWF of these classes
 */
private var _forceClassInclusion:Array = [ CSVMovieSource /*, StaticMovieSource, XMLMovieSource*/ ];

/** 
 * The URL from where to retrieve the Component Definitions XML
 */
private var _componentDefinitionsUrl:String = 'MovieAppComponentDefinitions.xml';

/**
 * The DIContainer which will hold and manage creating and caching instances and their dependencies
 */
public var container:DIContainer;

/**
 * The ComponentDefintionLoader instance that will be used to load the ComponentDefinitionsURL
 */
public var componentDefinitionsLoader:ComponentDefinitionsLoader;

/**
 * Bindable value indicating if the DIContainer is ready for use
 */
[Bindable] private var _containerComplete:Boolean = false;

/**
 * The MovieLister instance that will be queried for movie lists
 */
public var movieLister:MovieLister;

/**
 * Creates the container, and triggers the loading of the component defintions
 * <p>Could potentially be done earlier, say when childrenCreated() occurs, or initialized().</p>
 */
public function app_created( event:FlexEvent ):void
{
	logMessage( 'creating container, cache instances:', true, ', injection type:', 'setter' );
	// create the container with sensible defaults	
	container = new DefaultDIContainer({ cache: true, injectionType: 'setter' });

	// register instance so we can populate some values the first time its retrieved
	container.registerInstance( MovieApp, this, [{movieLister: MovieLister}], {setParameters: 'once'} );
	
	logMessage( 'loading component defintions from:', _componentDefinitionsUrl );
	// start loading the component definition xml
	componentDefinitionsLoader = new ComponentDefinitionsLoader( container, new XMLComponentDefinitionsParser(), new URLRequest( _componentDefinitionsUrl ) );
	componentDefinitionsLoader.addEventListener( Event.COMPLETE, componentDefinitionLoader_complete );
	componentDefinitionsLoader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, componentDefinitionLoader_securityError );
	componentDefinitionsLoader.addEventListener( IOErrorEvent.IO_ERROR, componentDefinitionLoader_ioError );
}

/**
 * Set values on the MovieApp, signify the DIContainer is ready
 */
private function componentDefinitionLoader_complete( event:Event ):void
{
	// retrieving this instance (even though its the same as this) will set the movieLister property to an instance of MovieLister
	var app:MovieApp = container.getInstance( MovieApp ) as MovieApp;
	
	// alternatively we could just do this: 
	//movieLister = container.getInstance( MovieLister ) as MovieLister;	

	// set to true as we have components waiting on this bindable value
	_containerComplete = true;
}

/**
 * logs a message if the component defintions could not be loaded due to a security error
 */
private function componentDefinitionLoader_securityError( event:SecurityErrorEvent ):void
{
	logMessage( 'security eroror loading component defintions:', event );	
}

/**
 * logs a message if the component defintions could not be loaded due to an IO error
 */
private function componentDefinitionLoader_ioError( event:IOErrorEvent ):void
{
	logMessage( 'io error loading component definitions:', event );
}

/** 
 * If a director is set shows movies by that director
 * Otherwise shows all movies
 */
public function getMoviesButton_click( event:Event ):void
{
	var director:String = directorTextInput.text;
	
	var movies:Array = (director == "") 
		? movieLister.getAll() 
		: movieLister.getMoviesDirectedBy( director );
	
	logMessage( (movies ? movies.length : 0), 'movie(s) found' );
	
	// show all movie matches
	if( movies ) movies.forEach( function( movie:Movie, index:int, array:Array ):void
	{
		logMessage( 'movie #', Number(index + 1).toString(), ':', movie.toString() );
	});	
}

/**
 * Writes a message to the text field and to the trace output
 */
private function logMessage( ...args ):void
{
	if( !args ) return;

	// add time as first item in args
	args.unshift( (new Date()).toTimeString() );
	
	var msg:String = args.join(' ');
	textArea.text += msg + '\n';
	trace( msg );
}